Published 2021-04-22
React Hooks
Hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。
- useState
- useEffect
- useRef
- useContext
- useCallback
- useMemo
使用 useState
useState
可以让你在不编写 class 的情况下使用 state。
import {useState} from 'react'
function Counter() {
const [count, setCount] = useState(0)
function updateCount() {
setCount(count + 1)
}
return <button onClick={updateCount}>Count is: {count}</button>
}
useState
第一个参数是初始值,第二个参数是一个函数,这个函数可以更新初始值。
如果更新函数返回值与初始值相同,那么组件不会更新。否则将组件的重新渲染加入队列。
使用 useEffect
useEffect(callback[, dependencies]);
callback
是包含副作用逻辑的函数dependencies
是一个数组,表示依赖的数据发生变化时,callback
函数才会执行。
当dependecies
未提供时,每次渲染都会执行callback
函数。
当dependencies
提供的是一个空数组时,callback
函数只会执行一次。
当dependencies
提供的是一个不为空的数组时,callback
函数会在依赖的数据发生变化时执行。
import {useEffect} from 'react'
function MyComponent() {
useEffect(() => {
// perform side effect here
}, [])
}
A Simple Explanation of React.useEffect()
使用 useRef
useRef
允许直接访问 JSX 元素的 DOM 元素。
import {useRef} from 'react'
function MyComponent() {
const ref = useRef()
return <div ref={ref} />
}
此时,可以使用ref.current
访问到 DOM 元素。比如:
import {useWindowEvent} from '@mantine/hooks'
import {useRef} from 'react'
function Header() {
const inputRef = useRef()
useWindowEvent('keydown', (event) => {
if (event.code === 'KeyK' && event.ctrlKey) {
event.preventDefault()
inputRef.current.focus()
}
})
return <input ref={inputRef} />
}
使用 useContext
useContext
提供比Context.Consumer
更简单的方式来访问 Context。比如:
import { createContext, useContext } from 'react';
const NameContext = createContext('');
function App() {
return (
<NameContext.Provider value="John Doe">
<Body />
<NameContext.Provider>
);
}
function Body() {
return <Greeting />;
}
function Greeting() {
const name = useContext(NameContext);
return (
<h1>Welcome, {name}</h1>
);
}
使用 useCallback
useCallback
返回一个 memoized 函数,这个函数会在组件的每次渲染时被调用。
useCallback(fn,deps)
,类似于 vue 中的 computed
function App() {
const [player, setPlayer] = React.useState('')
const [players, setPlayers] = React.useState(['Messi', 'Ronaldo', 'Laspada'])
function handleChangeInput(event) {
setPlayer(event.target.value)
}
function handleAddPlayer() {
setPlayers(players.concat(player))
}
const handleRemovePlayer = useCallback(
(player) => {
setPlayers(players.filter((p) => p !== player))
},
[players]
)
return (
<>
<input onChange={handleChangeInput} />
<button onClick={handleAddPlayer}>Add Player</button>
<PlayerList players={players} handleRemovePlayer={handleRemovePlayer} />
</>
)
}
function PlayerList({players, handleRemovePlayer}) {
return (
<ul>
{players.map((player) => (
<li key={player} onClick={() => handleRemovePlayer(player)}>
{player}
</li>
))}
</ul>
)
}
使用 useMemo
useMemo
返回一个 memoized 值,与useEffect
、useCallback
类似,接收函数和依赖项作为参数。
import * as React from 'react'
import {getMDXComponent} from 'mdx-bundler/client'
function Post({code, frontmatter}) {
const Component = React.useMemo(() => getMDXComponent(code), [code])
return (
<>
<header>
<h1>{frontmatter.title}</h1>
<p>{frontmatter.description}</p>
</header>
<main>
<Component />
</main>
</>
)
}
Comments
No Comments!